/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.yxw.live_vod_boot.utils;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/*** 
 * MacUtil
*@author hjx
*@date 2024/1/16 14:06:22
*@update 2024/1/16 14:06:22
*
**/
public class MacUtil
{
    public static String ErrorMessage = "";

    private String sRemoteAddr;
    private int iRemotePort = 137;
    private byte[] buffer = new byte[1024];
    private DatagramSocket ds = null;
    public MacUtil(String strAddr)
    {
        // throws Exception
        sRemoteAddr = strAddr;
        try
        {
            ds = new DatagramSocket();
        }
        catch(Exception e)
        {
            ds = null;
            ErrorMessage = e.getMessage();
            System.out.println(ErrorMessage);
        }
    }
    protected final DatagramPacket send(final byte[] bytes) throws IOException {
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length, InetAddress
                .getByName(sRemoteAddr), iRemotePort);
        ds.send(dp);
        return dp;
    }
    protected final DatagramPacket receive() throws Exception {
        DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
        ds.receive(dp);
        return dp;
    }
    // 询问包结构:
    // Transaction ID 两字节（16位） 0x00 0x00
    // Flags 两字节（16位） 0x00 0x10
    // Questions 两字节（16位） 0x00 0x01
    // AnswerRRs 两字节（16位） 0x00 0x00
    // AuthorityRRs 两字节（16位） 0x00 0x00
    // AdditionalRRs 两字节（16位） 0x00 0x00
    // Name:array [1..34] 0x20 0x43 0x4B 0x41(30个) 0x00 ;
    // Type:NBSTAT 两字节 0x00 0x21
    // Class:INET 两字节（16位）0x00 0x01
    protected byte[] getQueryCmd() throws Exception {
        byte[] t_ns = new byte[50];
        t_ns[0] = 0x00;
        t_ns[1] = 0x00;
        t_ns[2] = 0x00;
        t_ns[3] = 0x10;
        t_ns[4] = 0x00;
        t_ns[5] = 0x01;
        t_ns[6] = 0x00;
        t_ns[7] = 0x00;
        t_ns[8] = 0x00;
        t_ns[9] = 0x00;
        t_ns[10] = 0x00;
        t_ns[11] = 0x00;
        t_ns[12] = 0x20;
        t_ns[13] = 0x43;
        t_ns[14] = 0x4B;
        for (int i = 15; i < 45; i++) {
            t_ns[i] = 0x41;
        }
        t_ns[45] = 0x00;
        t_ns[46] = 0x00;
        t_ns[47] = 0x21;
        t_ns[48] = 0x00;
        t_ns[49] = 0x01;
        return t_ns;
    }
    // 表1 “UDP－NetBIOS－NS”应答包的结构及主要字段一览表
    // 序号 字段名 长度
    // 1 Transaction ID 两字节（16位）
    // 2 Flags 两字节（16位）
    // 3 Questions 两字节（16位）
    // 4 AnswerRRs 两字节（16位）
    // 5 AuthorityRRs 两字节（16位）
    // 6 AdditionalRRs 两字节（16位）
    // 7 Name<Workstation/Redirector> 34字节（272位）
    // 8 Type:NBSTAT 两字节（16位）
    // 9 Class:INET 两字节（16位）
    // 10 Time To Live 四字节（32位）
    // 11 Length 两字节（16位）
    // 12 Number of name 一个字节（8位）
    // NetBIOS Name Info 18×Number Of Name字节
    // Unit ID 6字节（48位
    protected final String getMacAddr(byte[] brevdata) throws Exception {
        // 获取计算机名
        int i = brevdata[56] * 18 + 56;
        String sAddr = "";
        StringBuffer sb = new StringBuffer(17);
        // 先从第56字节位置，读出Number Of Names（NetBIOS名字的个数，其中每个NetBIOS Names
        // Info部分占18个字节）
        // 然后可计算出“Unit ID”字段的位置＝56＋Number Of
        // Names×18，最后从该位置起连续读取6个字节，就是目的主机的MAC地址。
        for (int j = 1; j < 7; j++) {
            sAddr = Integer.toHexString(0xFF & brevdata[i + j]);
            if (sAddr.length() < 2) {
                sb.append(0);
            }
            sb.append(sAddr.toUpperCase());
            if (j < 6)
                sb.append('-');
        }
        return sb.toString();
    }
    public final void close() {
        try {
            ds.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    public final String getRemoteMacAddr()// throws Exception
    {
        if(null != ds)
        {
            try
            {
                byte[] bqcmd = getQueryCmd();
                send(bqcmd);
                DatagramPacket dp = receive();
                String smac = getMacAddr(dp.getData());
                close();
                return smac;   
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
                return "";
            } 
        }
        else
        {
            return "";
        }
    }    

    public static String what(String ip) //throws SocketException, UnknownHostException
    {
        InetAddress RemotHost = null;
        try
        {
            RemotHost = InetAddress.getByName(ip); //InetAddress.getByName(ip); new InetAddress()
            System.out.println(RemotHost.getHostAddress());
        }
        catch(UnknownHostException e)
        {
            RemotHost = null;
            ErrorMessage = e.getMessage();
            System.out.println(ErrorMessage);
            return "";
        }        
	NetworkInterface ne = null;
        try
        {
            ne = NetworkInterface.getByInetAddress(RemotHost);
        }
        catch(SocketException e)
        {
            ne = null;
            ErrorMessage = e.getMessage();
            System.out.println(ErrorMessage);
            return "";
        }
	byte[]mac ;        
        try
        {
            mac = ne.getHardwareAddress();
        }
        catch(SocketException e)
        {
            //ne = null;
            ErrorMessage = e.getMessage();
            System.out.println(ErrorMessage);
            return "";
        }
        catch(Exception e)
        {
            //ne = null;
            ErrorMessage = e.getMessage();
            System.out.println(ErrorMessage);
            return "";
        }
	StringBuilder sb = new StringBuilder("");
	for(int i=0; i<mac.length; i++)
        {
            if(i!=0)
            {
                sb.append("-");
            }
            //字节转换为整数
            int temp = mac[i]&0xff;
            String str = Integer.toHexString(temp);
            //System.out.println("每8位:"+str);
            if(str.length()==1) 
            {
                sb.append("0"+str);
            }
            else
            {
                sb.append(str);
            }
	}
	return sb.toString().toUpperCase();
    }    
    
    public static class MacUtilInner
    {
        public static String getLocalMacByIp(String ip) throws SocketException, IOException{
            NetworkInterface ne=NetworkInterface.getByInetAddress(InetAddress.getByName(ip));
            byte[]mac=ne.getHardwareAddress();
            String mac_s=hexByte(mac[0])+"-"+
            hexByte(mac[1])+"-"+ 
            hexByte(mac[2])+"-"+
            hexByte(mac[3])+"-"+ 
            hexByte(mac[4])+"-"+
            hexByte(mac[5]);
            return mac_s;
        }

        private static String  hexByte(byte b)
            {
                String s="000000"+Integer.toHexString(b);
                return s.substring(s.length()-2);
            }

        /**
         * 获取当前操作系统名称. return 操作系统名称 例如:windows,Linux,Unix等.
         */
        public static String getOSName() {
            return System.getProperty("os.name").toLowerCase();
        }

        /**
         * 获取Unix网卡的mac地址.
         * 
         * @return mac地址
         */
        public static String getUnixMACAddress() {
            String mac = null;
            BufferedReader bufferedReader = null;
            Process process = null;
            try {
                /**
                 * Unix下的命令，一般取eth0作为本地主网卡 显示信息中包含有mac地址信息
                 */
                process = Runtime.getRuntime().exec("ifconfig eth0");
                bufferedReader = new BufferedReader(new InputStreamReader(
                        process.getInputStream()));
                String line = null;
                int index = -1;
                while ((line = bufferedReader.readLine()) != null) {
                    /**
                     * 寻找标示字符串[hwaddr]
                     */
                    index = line.toLowerCase().indexOf("hwaddr");
                    /**
                     * 找到了
                     */
                    if (index != -1) {
                        /**
                         * 取出mac地址并去除2边空格
                         */
                        mac = line.substring(index + "hwaddr".length() + 1).trim();
                        break;
                    }
                }
            } catch (IOException e) {
                e.getMessage();
            } finally {
                try {
                    if (bufferedReader != null) {
                        bufferedReader.close();
                    }
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                bufferedReader = null;
                process = null;
            }
            return mac;
        }

        /**
         * 获取Linux网卡的mac地址.
         * 
         * @return mac地址
         */
        public static String getLinuxMACAddress() {
            String mac = null;
            BufferedReader bufferedReader = null;
            Process process = null;
            try {
                /**
                 * linux下的命令，一般取eth0作为本地主网卡 显示信息中包含有mac地址信息
                 */
                process = Runtime.getRuntime().exec("ifconfig eth0");
                bufferedReader = new BufferedReader(new InputStreamReader(
                        process.getInputStream()));
                String line = null;
                int index = -1;
                while ((line = bufferedReader.readLine()) != null) {
                    index = line.toLowerCase().indexOf("硬件地址");
                    /**
                     * 找到了
                     */
                    if (index != -1) {
                        /**
                         * 取出mac地址并去除2边空格
                         */
                        mac = line.substring(index + 4).trim();
                        break;
                    }
                }
            } catch (IOException e) {
                e.getMessage();
            } finally {
                try {
                    if (bufferedReader != null) {
                        bufferedReader.close();
                    }
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                bufferedReader = null;
                process = null;
            }

            return mac;
        }

        /**
         * 获取widnows网卡的mac地址.
         * 
         * @return mac地址
         */
        public static String getWindowsMACAddress() {
            String mac = null;
            BufferedReader bufferedReader = null;
            Process process = null;
            try {
                /**
                 * windows下的命令，显示信息中包含有mac地址信息
                 */
                process = Runtime.getRuntime().exec("ipconfig /all");
                bufferedReader = new BufferedReader(new InputStreamReader(
                        process.getInputStream(), "GBK")); // windows系统都是GBK编码，不加GBK读出的中文是乱码
                String line = null;
                int index = -1;
                while ((line = bufferedReader.readLine()) != null) {
                    /**
                     * 寻找标示字符串[physical address]
                     */
                    index = line.toLowerCase().indexOf("physical address");
                    if (index == -1) {
                        /**
                         * 寻找标示字符串[物理地址]
                         */
                        index = line.toLowerCase().indexOf("物理地址");

                    }

                    if (index != -1) {
                        index = line.indexOf(":");
                        if (index != -1) {
                            /**
                             * 取出mac地址并去除2边空格
                             */
                            mac = line.substring(index + 1).trim();
                        }
                        break;
                    }
                }
            } catch (IOException e) {
                e.getMessage();
            } finally {
                try {
                    if (bufferedReader != null) {
                        bufferedReader.close();
                    }
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                bufferedReader = null;
                process = null;
            }
            return mac;
        }

        /**
         * 获取widnows网卡的mac地址.
         * 
         * @return mac地址
         */
        public static String getWindowsMACAddress(String ip) {
            String mac = null;
            BufferedReader bufferedReader = null;
            Process process = null;
            try {
                /**
                 * windows下的命令，显示信息中包含有mac地址信息
                 */
                // process = Runtime.getRuntime().exec("ipconfig /all");
                process = Runtime.getRuntime().exec("nbtstat -A " + ip);
                bufferedReader = new BufferedReader(new InputStreamReader(
                        process.getInputStream(), "GBK")); // windows系统都是GBK编码，不加GBK读出的中文是乱码
                String line = null;
                int index = -1;
                while ((line = bufferedReader.readLine()) != null) {
                    /**
                     * 寻找标示字符串[physical address]
                     */
                     index = line.toLowerCase().indexOf("mac 地址 =");

                    if (index != -1) {
                        index = line.indexOf("=");
                        if (index != -1) {
                            /**
                             * 取出mac地址并去除2边空格
                             */
                            mac = line.substring(index + 1).trim();
                        }
                        break;
                    }
                }
            } catch (IOException e) {
                e.getMessage();
            } finally {
                try {
                    if (bufferedReader != null) {
                        bufferedReader.close();
                    }
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                bufferedReader = null;
                process = null;
            }
            return mac;
        }

        /**
         * 获取客户端mac
         * 
         * @description {TODO}
         * @return
         */
        public static String getMACAddress(String ip) {
            String os = getOSName();
            String mac = "";
            if (os.startsWith("windows")) {
                mac = getWindowsMACAddress(ip);
            } else if (os.startsWith("linux")) {
                mac = getLinuxMACAddress();
            } else {
                mac = getUnixMACAddress();
            }
            return mac;
        }  
    }
  
}
